package us.mmapp.services;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.auth.BasicScheme;
import org.json.JSONException;
import org.json.JSONObject;

import us.mmapp.interfaces.MediaUploaderListener;
import us.mmapp.util.ApplicationData;
import us.mmapp.util.HttpManager;
import us.mmapp.util.ServicesUtils;
import us.mmapp.util.TextUtils;
import android.os.AsyncTask;
import android.util.Log;

public class MediaUploader
{
	private void MediaUploader() {}
	
	private static long requestId;
	
	private static ArrayList<MediaUploaderListener> listeners;
	
	public static void attach(MediaUploaderListener listener)
	{
		if (listeners == null)
			listeners = new ArrayList<MediaUploaderListener>();
		listeners.add(listener);
	}
	
	public static void deattach(MediaUploaderListener listener)
	{
		if (listeners != null && listeners.contains(listener))
			listeners.remove(listener);
	}
	
	/**
	 * Announce the fail.
	 * 
	 * @param reqId the id of the request that was succesful.
	 * @param msg
	 */
	private static void fail(long reqId, String msg)
	{
		Log.v("UPLOAD REQUEST", "FAIL ON " + reqId + " with " + msg);
		if (listeners != null)
			for (MediaUploaderListener l : listeners)
				l.onMediaUploaderFail(reqId, msg);
	}
	
	/**
	 * Announce the success.
	 * 
	 * @param reqId the id of the request that was succesful.
	 */
	private static void success(long reqId)
	{
		Log.v("UPLOAD REQUEST", "SUCCESS ON " + reqId);
		if (listeners != null)
			for (MediaUploaderListener l : listeners)
				l.onMediaUploaderSuccess(reqId);
	}
	
	/**
	 * Make a request for an upload. mediatPath and thumbPath can be null, empty
	 * 
	 * @param mediaPath
	 * @param thumbPath
	 * @param objectId the id of the object
	 * @return the requestId
	 */
	public static synchronized long makeRequest(String mediaPath, String thumbPath, long objectId)
	{
		++requestId;
		Log.v("UPLOAD REQUEST", "" + requestId + " " + mediaPath + " " + thumbPath + " of " + objectId);
		AsyncTask<String, Void, Object[]> t = new AsyncTask<String, Void, Object[]>()
		{
			@Override
			protected Object[] doInBackground(String... params)
			{
				Object[] ret = {upload(params[0], params[1], params[2], params[3], params[4]), params[5]};
				return ret;
			}		
			@Override
			protected void onPostExecute(Object[] result)
			{
				long requestId = Long.parseLong(((String)result[1]));
				if (result[0] == null)
				{
					fail(requestId, "Server cannot be reached.");
					return;
				}
				JSONObject res = (JSONObject) result[0];
				
				try
				{
					String msg = res.getString("error");
					fail(requestId, msg);
				} catch (JSONException e)
				{
					success(requestId);
				}				
			}
		};
		String[] params = {ApplicationData.getUsername(), ApplicationData.getPassword(),
				mediaPath, thumbPath, objectId + "", requestId + ""};
		t.execute(params);
		return requestId;
	}
	
	private static JSONObject upload(String username, String userpass, String mediaPath, String thumbPath, String objectId)
	{
		JSONObject ret = null;
		try
		{
			MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
			
			//Add all parts
			if (mediaPath != null && mediaPath != "")
			{
				entity.addPart("media_file", new FileBody(new File (mediaPath)));
			}
			
			if (thumbPath != null && thumbPath != "")
			{
				entity.addPart("thumb", new FileBody(new File (thumbPath)));
			}
			
	    	entity.addPart("object_id", new StringBody(objectId));
	    	
			HttpPost post = new HttpPost(ServicesUtils.UPLOAD_FILE);
			post.addHeader(BasicScheme.authenticate(
	    			new UsernamePasswordCredentials(username,TextUtils.md5(userpass)),
	    			"UTF-8",
	    			false)); 	
	    	post.setEntity(entity);
	   
	    	HttpResponse httpResponse = HttpManager.execute(post);
	    	HttpEntity responseEntity = httpResponse.getEntity();
	    	
            if (responseEntity != null)
            {
            	
                InputStream instream = responseEntity.getContent();
                String result = TextUtils.convertStreamToString(instream);           
                instream.close();
                // Try converting result to JSON
                Log.e("UPLOADER", "Result: " + httpResponse);
                try
                {
					ret = new JSONObject(result);
				}
                catch (JSONException e)
				{
					Log.e("UPLOADER", "Could not parse JSON.");
					ret = null;
				}
            }
		}
		catch (IOException e)
		{}
		return ret;
	}

}
